package net.fornwall.eclipsecoder.javasupport;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Pattern;

import org.eclipse.jdt.core.JavaCore;
import org.eclipse.jdt.core.dom.AST;
import org.eclipse.jdt.core.dom.ASTParser;
import org.eclipse.jdt.core.dom.Comment;
import org.eclipse.jdt.core.dom.CompilationUnit;
import org.eclipse.jdt.core.dom.Message;

// NOT USED - just a scratchpad
public class SourceStripper {

    @SuppressWarnings("unchecked")
    public static void main(String[] args) throws Exception {
        System.out.println("MATCH: "
                + Pattern.compile("^ *?\n", Pattern.DOTALL).matcher("  \nasdf").find());
        assertEquals("class X {}", stripComments("//this is a class\nclass X {}"));
        assertEquals("class X {\n}",
                stripComments("//this is a class\nclass X {\n//comment inside\n}"));
        assertEquals("class X {\n  public void go() { } }", "class X {\n  public void go() { } }");
        assertEquals(
                "class X {\n  public void go() { } }",
                stripComments("//this is a class\nclass X {\n  //do nothing\n  public void go() { } }"));

        String source = "// just a test\n" + "public class Test {\n"
                + "  public static void shout(String what) {\n"
                + "    ((java.io.PrintStream) System.out).println(\"Shouting: \" + what);\n"
                + "  }\n" + "}\n";

        CompilationUnit astTree = JavaLanguageSupport.parse(source);
        astTree.accept(new Visitor(new ArrayList<Integer>()));
        for (Comment c : (List<Comment>) astTree.getCommentList()) {
            System.out.println("Comment : " + c);
        }

        for (Message m : astTree.getMessages()) {
            System.out.println("MESSAGE: " + m.getMessage());
        }
        System.out.println("Done");

    }

    @SuppressWarnings("unchecked")
    public static String stripComments(String source) throws Exception {
        // System.out.println("STRIPPING FROM ### " + source);
        CompilationUnit compilationUnit = (CompilationUnit) getParser(source).createAST(null);
        List<Comment> commentList = compilationUnit.getCommentList();
        int lastPos = 0;
        StringBuffer buffer = new StringBuffer();
        for (Comment comment : commentList) {
            // comment.delete() does not work as a Comment is unparented
            buffer.append(source.substring(lastPos, comment.getStartPosition()));
            lastPos = comment.getStartPosition() + comment.getLength();
        }
        buffer.append(source.substring(lastPos, source.length()));
        StringBuilder result = new StringBuilder();
        // System.out.println("BEFORE: " + buffer.toString());
        for (String line : buffer.toString().split("\n")) {
            if (line.trim().length() > 0)
                result.append(line + "\n");
        }
        result.deleteCharAt(result.length() - 1);
        return result.toString();
        //        
        //        
        // Document doc = new Document(source);
        // CompilationUnit compilationUnit = (CompilationUnit) getParser(source).createAST(null);
        // ASTRewrite rewriter = ASTRewrite.create(compilationUnit.getAST());
        // compilationUnit.recordModifications();
        // for (Comment c : (List<Comment>) compilationUnit.getCommentList()) {
        // //rewriter.remove(c, null);
        // compilationUnit.accept(new Visitor(new ArrayList<Integer>()));
        // System.out.println("PARENT: " + c.getParent());
        //            
        // }
        // compilationUnit.rewrite(doc, null).apply(doc);
        // //rewriter.rewriteAST().apply(doc);
        // return doc.get();
    }

    /**
     * Utility method for getting the AST parser for source.
     * 
     * @param source
     *            the java 1.5 compatible source code
     * @return a parser of the supplied source code
     */
    @SuppressWarnings("unchecked")
    private static ASTParser getParser(String source) {
        Map<String, String> compilerOptions = new HashMap<String, String>(); // JavaCore.getOptions();
        compilerOptions.put(JavaCore.COMPILER_SOURCE, JavaCore.VERSION_1_5);
        compilerOptions.put(JavaCore.COMPILER_COMPLIANCE, JavaCore.VERSION_1_5);

        ASTParser parser = ASTParser.newParser(AST.JLS3);
        parser.setKind(ASTParser.K_COMPILATION_UNIT);
        parser.setSource(source.toCharArray());
        parser.setResolveBindings(true);
        parser.setCompilerOptions(compilerOptions);
        return parser;
    }

    public static void assertEquals(String expected, String actual) {
        if (!expected.equals(actual)) {
            System.err.println("Failed! Expected '" + expected + "', was '" + actual + "'");
        } else {
            System.out.println("OK");
        }
    }
}
